package com.prisetree.isv.service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;

import javax.annotation.Resource;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.CorpMessageCorpconversationAsyncsendRequest;
import com.dingtalk.api.response.CorpMessageCorpconversationAsyncsendResponse;
import com.dingtalk.isv.access.api.service.corp.CorpManageService;
import com.dingtalk.isv.access.biz.prisetree.dao.OfficeBookingsMapper;
import com.dingtalk.isv.access.biz.prisetree.dao.OfficeResourcesMapper;
import com.dingtalk.isv.access.biz.prisetree.dao.OrderRefuseReasonsMapper;
import com.dingtalk.isv.access.biz.prisetree.dao.OrdersMapper;
import com.dingtalk.isv.access.biz.prisetree.dao.SysRichtextDictMapper;
import com.prisetree.isv.common.constant.ConstantsUtil;
import com.prisetree.isv.common.constant.SystemCode;
import com.prisetree.isv.common.util.CommonDateUtil;
import com.prisetree.isv.common.util.DictUtils;
import com.prisetree.isv.common.util.IdGen;
import com.prisetree.isv.common.util.SuiteConfig;
import com.prisetree.isv.domain.OfficeResources;
import com.prisetree.isv.domain.OrderRefuseReasons;
import com.prisetree.isv.domain.Orders;
import com.prisetree.isv.domain.SysRichtextDict;
import com.prisetree.isv.domain.query.OrderRefuseReasonsExample;
import com.prisetree.isv.domain.query.OrdersExample;
import com.prisetree.isv.domain.query.SysRichtextDictExample;
import com.prisetree.isv.request.parameter.CreateOrdersRequest;
import com.taobao.api.ApiException;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

@Service
@Transactional(readOnly = true)
public class OrdersService {

	@Autowired
	OrdersMapper ordersMapper;
	@Autowired
	OfficeResourcesMapper officeResourcesMapper;
	@Autowired
	OrderRefuseReasonsMapper orderRefuseReasonsMapper;
	@Autowired
	OfficeBookingsMapper officeBookingsMapper;
	@Autowired
	SysRichtextDictMapper sysRichtextDictMapper;
	@Resource
    private CorpManageService corpManageService;
	
	public SystemCode insert(CreateOrdersRequest req, String token){
		if(StringUtils.isBlank(req.getToken()) || StringUtils.isBlank(token) || !StringUtils.equals(req.getToken(), token)) {
			return SystemCode.ERROR_OPERATION;
		}
		
		ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
		Validator validator = factory.getValidator();
		
		Set<ConstraintViolation<CreateOrdersRequest>> resSet = validator.validate(req);
		if(!resSet.isEmpty()) {
			//返回错误信息
			String errorInfo = "";
			for (ConstraintViolation<CreateOrdersRequest> item : resSet) {  
				errorInfo += item.getPropertyPath() + "：" + item.getMessage() + "，";
	        }
			errorInfo = errorInfo.substring(0, errorInfo.length() - 1);
			SystemCode.PARAMETER_TOOLONG.setDesc(errorInfo);
			return SystemCode.PARAMETER_TOOLONG;
		}
		
		if(StringUtils.isBlank(req.getOfficeResourcesId()) || officeResourcesMapper.selectByPrimaryKey(req.getOfficeResourcesId()) == null) {
			return SystemCode.OFFICE_RESOURCES_NOTFOUND;
		}
		Orders order = new Orders();
		order.setId(IdGen.uuid());
		order.setOrderNumber("" + System.currentTimeMillis() + (int)((Math.random()*9+1)*1000));
		order.setOfficeResourcesId(req.getOfficeResourcesId());
		order.setOfficeResourcesName(req.getOfficeResourcesName());
		order.setOfficeResourcesRentId(req.getOfficeResourcesRentId());
		order.setOfficeResourcesRentName(req.getOfficeResourcesRentName());
		order.setOfficeResourcesAddr(req.getOfficeResourcesAddr());
		order.setOfficeResourcesMobile(req.getOfficeResourcesMobile());
		order.setCompanyId(req.getCompanyId());
		order.setCompanyName(req.getCompanyName());
		order.setCompanyMobile(req.getCompanyMobile());
		order.setUnit(req.getUnit());
		order.setBillingMode(req.getBillingMode());
		order.setEnterTime(req.getEnterTime());
		order.setLeaveTime(req.getLeaveTime());
		order.setStationNum(req.getStationNum());
		order.setUnitPrice(req.getUnitPrice());
		order.setArea(req.getArea());
		order.setUsageRate(req.getUsageRate());
		order.setState(ConstantsUtil.ORDER_STATE_DOING);
		order.setType(req.getType());
		order.setStationType(req.getStationType());
		order.setCreateDate(new Date());
		order.setDingUserId(req.getDingUserId());
		
		double total = 0.0;
		if (StringUtils.equals(req.getType(), "1")) {
			//写字楼
			total = order.getUnit() * order.getUnitPrice() * 12;
		} else {
			//临时、固定
			total = order.getUnit() * order.getUnitPrice() * order.getStationNum();
		}
		BigDecimal b = new BigDecimal(total);  
		total = b.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
		if(total != req.getTotalPrice()){
			return SystemCode.PRICE_ERROR;
		}
		order.setTotalPrice(req.getTotalPrice());
		order.setDeposit(req.getDeposit());
		int res = ordersMapper.insert(order);
		if (res != 1) {
			return SystemCode.CREATE_ORDERS_FAIL;
		}
		this.sendMessageToDingUser(order);
		SystemCode.SUCCESS.setResultObject(order);
		return SystemCode.SUCCESS;
	}

	public SystemCode delete(String id) {
		int a = ordersMapper.deleteByPrimaryKey(id);
		if (a != 1) {
        	return SystemCode.DELETE_ORDERS_FAIL;
        }
        return SystemCode.SUCCESS;
	}
	
	public SystemCode findOrderListBytype(String type, String state, String corpId) {
		if(StringUtils.isBlank(corpId)) {
			return SystemCode.TRY_TO_RELOGIN;
		}
		if(StringUtils.isBlank(type)) {
			return SystemCode.MISSING_PARAMETER;
		}
		
		if(StringUtils.isBlank(state)) {
			return SystemCode.MISSING_PARAMETER;
		}
		
		List<String> types = new ArrayList<String>();
		if(StringUtils.equals(type, "all")) {
			//全部列表
			if (Integer.valueOf(state) != 3) {
				types.add(ConstantsUtil.ORDER_TYPE_BOOKING_LINSHI);
				types.add(ConstantsUtil.ORDER_TYPE_RENT_GUDING);
				types.add(ConstantsUtil.ORDER_TYPE_RENT_XIEZILOU);
			} else {
				types.add(ConstantsUtil.ORDER_TYPE_BOOKING_LOOK_GUDING);
				types.add(ConstantsUtil.ORDER_TYPE_BOOKING_LOOK_XIEZILOU);
			}
		}else if(StringUtils.equals(type, "linshi")) {
			//临时工位
			types.add(ConstantsUtil.ORDER_TYPE_BOOKING_LINSHI);
		}else if(StringUtils.equals(type, "guding")) {
			//固定工位
			if (Integer.valueOf(state) != 3) {
				types.add(ConstantsUtil.ORDER_TYPE_RENT_GUDING);
			} else {
				types.add(ConstantsUtil.ORDER_TYPE_BOOKING_LOOK_GUDING);
			}
		} else if(StringUtils.equals(type, "xiezilou")) {
			//写字楼
			if (Integer.valueOf(state) != 3) {
				types.add(ConstantsUtil.ORDER_TYPE_RENT_XIEZILOU);
			} else {
				types.add(ConstantsUtil.ORDER_TYPE_BOOKING_LOOK_XIEZILOU);
			}
		}
		
		OrdersExample example = new OrdersExample();
		//state:0预约中,1预约成功,2预约失败,3预约看场地
		if (Integer.valueOf(state) != 3) {
			example.createCriteria().andTypeIn(types).andCompanyIdEqualTo(corpId).andStateEqualTo(state);
		} else {
			example.createCriteria().andTypeIn(types).andCompanyIdEqualTo(corpId);
		}
		List<Orders> list = ordersMapper.selectByExample(example);
		JSONObject res = new JSONObject();
		JSONArray arr = new JSONArray();
		for(Orders item : list) {
			JSONObject json = new JSONObject();
			json.put("id", item.getId());
			json.put("resourceName", item.getOfficeResourcesName());
			json.put("resourceRentName", item.getOfficeResourcesRentName());
			json.put("type", item.getType());
			json.put("resourceTypeStr", getResourceTypeStr(item.getType()));
			json.put("state", item.getState());
			json.put("stateStr", getOrderStateStr(item.getState(), item.getType()));
			arr.add(json);
		}
		res.put("orderList", arr);
		
		//预定订单页qa数据
		SysRichtextDictExample richtextExample = new SysRichtextDictExample();
		richtextExample.createCriteria().andTypeEqualTo("order_booking_qa");
		List<SysRichtextDict> richtextList = sysRichtextDictMapper.selectByExampleWithBLOBs(richtextExample);
		res.put("qa", richtextList.get(0).getValue());
		
		SystemCode.SUCCESS.setResultObject(res);
		return SystemCode.SUCCESS;
	}

	public SystemCode listCount(String corpId) {
		if(StringUtils.isBlank(corpId)) {
			return SystemCode.TRY_TO_RELOGIN;
		}
		
		JSONObject json = new JSONObject();
		//统计数据
		List<Integer> countList = ordersMapper.countListByCorpId(corpId);
		json.put("yuyueNum", countList.get(0));
		json.put("doingNum", countList.get(1));
		json.put("successdNum", countList.get(2));
		json.put("failNum",  countList.get(3));
		//订单页qa数据
		SysRichtextDictExample richtextExample = new SysRichtextDictExample();
		richtextExample.createCriteria().andTypeEqualTo("order_qa");
		List<SysRichtextDict> richtextList = sysRichtextDictMapper.selectByExampleWithBLOBs(richtextExample);
		json.put("qa", richtextList.get(0).getValue());
		
        SystemCode.SUCCESS.setResultObject(json);
        return SystemCode.SUCCESS;
	}

	public SystemCode findYuyueListBytype(String type, String corpId) {
		if(StringUtils.isBlank(corpId)) {
			return SystemCode.TRY_TO_RELOGIN;
		}
		if(StringUtils.isBlank(type)) {
			return SystemCode.MISSING_PARAMETER;
		}
		
		List<String> types = new ArrayList<String>();
		if(StringUtils.equals(type, "all")) {
			//全部列表
			types.add(ConstantsUtil.ORDER_TYPE_BOOKING_LINSHI);
			types.add(ConstantsUtil.ORDER_TYPE_BOOKING_LOOK_GUDING);
			types.add(ConstantsUtil.ORDER_TYPE_BOOKING_LOOK_XIEZILOU);
		}else if(StringUtils.equals(type, "linshi")) {
			//预定临时工位
			types.add(ConstantsUtil.ORDER_TYPE_BOOKING_LINSHI);
		}else if(StringUtils.equals(type, "look")) {
			//预定看场地（固定、写字楼）
			types.add(ConstantsUtil.ORDER_TYPE_BOOKING_LOOK_GUDING);
			types.add(ConstantsUtil.ORDER_TYPE_BOOKING_LOOK_XIEZILOU);
		}
		
		OrdersExample example = new OrdersExample();
		example.createCriteria().andTypeIn(types).andCompanyIdEqualTo(corpId);
		List<Orders> list = ordersMapper.selectByExample(example);
		JSONObject res = new JSONObject();
		JSONArray arr = new JSONArray();
		for(Orders item : list) {
			JSONObject json = new JSONObject();
			json.put("id", item.getId());
			json.put("resourceName", item.getOfficeResourcesName());
			json.put("resourceRentName", item.getOfficeResourcesRentName());
			json.put("type", item.getType());
			json.put("resourceTypeStr", getResourceTypeStr(item.getType()));
			json.put("state", item.getState());
			json.put("stateStr", getOrderStateStr(item.getState(), item.getType()));
			arr.add(json);
		}
		res.put("orderList", arr);
		
		//预定订单页qa数据
		SysRichtextDictExample richtextExample = new SysRichtextDictExample();
		richtextExample.createCriteria().andTypeEqualTo("order_booking_qa");
		List<SysRichtextDict> richtextList = sysRichtextDictMapper.selectByExampleWithBLOBs(richtextExample);
		res.put("qa", richtextList.get(0).getValue());
		
		SystemCode.SUCCESS.setResultObject(res);
		return SystemCode.SUCCESS;
	}
	
	public SystemCode findShenheListBytype(String state, String corpId) {
		if(StringUtils.isBlank(corpId)) {
			return SystemCode.TRY_TO_RELOGIN;
		}
		if(StringUtils.isBlank(state)) {
			return SystemCode.MISSING_PARAMETER;
		}
		
		List<String> types = new ArrayList<String>();
		types.add(ConstantsUtil.ORDER_TYPE_RENT_GUDING);
		types.add(ConstantsUtil.ORDER_TYPE_RENT_XIEZILOU);
		
		OrdersExample example = new OrdersExample();
		example.createCriteria().andTypeIn(types).andCompanyIdEqualTo(corpId).andStateEqualTo(state);
		List<Orders> list = ordersMapper.selectByExample(example);
		JSONArray arr = new JSONArray();
		for(Orders item : list) {
			JSONObject json = new JSONObject();
			json.put("id", item.getId());
			json.put("resourceName", item.getOfficeResourcesName());
			json.put("resourceRentName", item.getOfficeResourcesRentName());
			arr.add(json);
		}
		SystemCode.SUCCESS.setResultObject(arr);
		return SystemCode.SUCCESS;
	}
	
	public SystemCode updateState(String id , String state) {
		OrdersExample example = new OrdersExample();
		example.createCriteria().andIdEqualTo(id);
		Orders order = ordersMapper.selectByPrimaryKey(id);
		if(order == null) {
			return SystemCode.ORDER_NOTFOUND;
		}
		order.setState(state);
		int a = ordersMapper.updateByExampleSelective(order, example);
		if (a != 1) {
        	return SystemCode.UPDATE_ORDERS_FAIL;
        }
        SystemCode.SUCCESS.setResultObject(order);
        return SystemCode.SUCCESS;
	}

	public SystemCode getDetailInfoById(String id) {
		Orders order = ordersMapper.selectByPrimaryKey(id);
		if(order == null) {
			return SystemCode.ORDER_NOTFOUND;
		}
		JSONObject json = new JSONObject();
		json.put("id", id);
		json.put("orderNumber", order.getOrderNumber());
		json.put("resourceName", order.getOfficeResourcesName());
		json.put("resourceRentName", order.getOfficeResourcesRentName());
		json.put("resourcesMobile", order.getOfficeResourcesMobile());
		json.put("state", order.getState());
		json.put("stateStr", getOrderStateStr(order.getState(), order.getType()));
		json.put("type", order.getType());
		json.put("typeStr", getResourceTypeStr(order.getType()));
		json.put("companyName", order.getCompanyName());
		json.put("companyMobile", order.getCompanyMobile());
		String enterTimeStr = "";
		if (order.getEnterTime() != null) {
			enterTimeStr = CommonDateUtil.format(order.getEnterTime(), "yyyy年MM月dd日");
		}
		json.put("enterTime",enterTimeStr);
		String leaveTimeStr = "";
		if (order.getEnterTime() != null) {
			leaveTimeStr = CommonDateUtil.format(order.getLeaveTime(), "yyyy年MM月dd日");
		}
		json.put("leaveTime",leaveTimeStr);
		json.put("stationNum", order.getStationNum());
		json.put("area", order.getArea());
		json.put("unit", order.getUnit());
		json.put("usageRate", order.getUsageRate());
		json.put("resourceAddr", order.getOfficeResourcesAddr());
		json.put("totalPrice", order.getTotalPrice());
		
		if (StringUtils.equals(order.getState(), ConstantsUtil.ORDER_STATE_FAIL)) {
			//审核未通过理由列表
			OrderRefuseReasonsExample example = new OrderRefuseReasonsExample();
			example.createCriteria().andOrderIdEqualTo(id);
			List<OrderRefuseReasons> list = orderRefuseReasonsMapper.selectByExample(example);
			JSONArray arr = new JSONArray();
			if (list != null && list.size() > 0) {
				for (OrderRefuseReasons reason : list) {
					JSONObject jsub = new JSONObject();
					jsub.put("reasonId", reason.getId());
					jsub.put("reason", reason.getReason());
					arr.add(jsub);
				}
			} 
			json.put("reasonList", arr);
		}
		
		SystemCode.SUCCESS.setResultObject(json);
		return SystemCode.SUCCESS;
	}

	public SystemCode contact(String id) {
		Orders order = ordersMapper.selectByPrimaryKey(id);
		if(order == null) {
			return SystemCode.ORDER_NOTFOUND;
		}
		OfficeResources resource = officeResourcesMapper.selectByPrimaryKey(order.getOfficeResourcesId());
		JSONObject json = new JSONObject();
		json.put("id", id);
		json.put("resourcesName", resource.getName());
		json.put("detailAddr", resource.getProvince() + resource.getCity() + resource.getArea() + resource.getDetailAddr());
		json.put("contactMobile", resource.getContactMobile());
		SystemCode.SUCCESS.setResultObject(json);
		return SystemCode.SUCCESS;
	}
	
	/**
	 * 获取根据type获取state对应文案
	 * @param state
	 * @return
	 */
	private String getOrderStateStr(String state, String type) {
		String stateStr = "";
		if(StringUtils.equals(type, ConstantsUtil.ORDER_TYPE_RENT_GUDING) 
				||StringUtils.equals(type, ConstantsUtil.ORDER_TYPE_RENT_XIEZILOU)) {
			//审核文案
			switch (state) {
			case ConstantsUtil.ORDER_STATE_DOING:
				stateStr = ConstantsUtil.ORDER_STATE_ZU_DOING_STR;
				break;
			case ConstantsUtil.ORDER_STATE_SUCCESS:
				stateStr = ConstantsUtil.ORDER_STATE_ZU_SUCCESS_STR;
				break;
			case ConstantsUtil.ORDER_STATE_FAIL:
				stateStr = ConstantsUtil.ORDER_STATE_ZU_FAIL_STR;
				break;
			default:
				stateStr = "未知类型";
				break;
			}
		} else {
			//预约文案
			switch (state) {
			case ConstantsUtil.ORDER_STATE_DOING:
				stateStr = ConstantsUtil.ORDER_STATE_BOOKING_DOING_STR;
				break;
			case ConstantsUtil.ORDER_STATE_SUCCESS:
				stateStr = ConstantsUtil.ORDER_STATE_BOOKING_SUCCESS_STR;
				break;
			case ConstantsUtil.ORDER_STATE_FAIL:
				stateStr = ConstantsUtil.ORDER_STATE_BOOKING_FAIL_STR;
				break;
			default:
				stateStr = "未知类型";
				break;
			}
		}
		return stateStr;
	}
	
	/**
	 * 获取房源类型对应Str
	 * @param state
	 * @return
	 */
	private String getResourceTypeStr(String type) {
		String resourceTypeStr = "";
		switch (type) {
		case ConstantsUtil.ORDER_TYPE_RENT_GUDING:
		case ConstantsUtil.ORDER_TYPE_BOOKING_LOOK_GUDING:
			resourceTypeStr = ConstantsUtil.RESOURCE_TYPE_GUDING_STR;
			break;
		case ConstantsUtil.ORDER_TYPE_RENT_XIEZILOU:
		case ConstantsUtil.ORDER_TYPE_BOOKING_LOOK_XIEZILOU:
			resourceTypeStr = ConstantsUtil.RESOURCE_TYPE_XIEZILOU_STR;
			break;
		case ConstantsUtil.ORDER_TYPE_BOOKING_LINSHI:
			resourceTypeStr = ConstantsUtil.RESOURCE_TYPE_LINSHI_STR;
			break;
		default:
			resourceTypeStr = "未知类型";
			break;
		}
		return resourceTypeStr;
	}

	private void sendMessageToDingUser(Orders order)
	{
		String userId = order.getDingUserId();
		String corpId = order.getCompanyId();
		String suiteKey = SuiteConfig.SUITE_KEY;
		Long agentId = corpManageService.getCorpApp(corpId, SuiteConfig.APP_ID).getResult().getAgentId();
		String access_token = corpManageService.getCorpToken(suiteKey, corpId).getResult().getCorpToken();
		System.out.println("userId=" + userId + ";corpId=" + corpId + ";suiteKey=" + suiteKey + ";access_token=" + access_token + ";agentId=" + agentId);
		String messageUrl = "https://isv.prisetree.com/isv-dd-service/?dd_nav_bgcolor=fff6f6f7&corpId=" + corpId;
		
		DingTalkClient client = new DefaultDingTalkClient("https://eco.taobao.com/router/rest");
		String img = DictUtils.getDictValue("img", "ding_message_corpconversation", null);
		img = StringUtils.isNotEmpty(img) ? ",\"image\": \"@" + img + "\"" : "";
		String tel = DictUtils.getDictValue("tel", "ding_message_corpconversation", "13676400750");
		String title = DictUtils.getDictValue("title", "ding_message_corpconversation", "预定通知");
		String hColor = DictUtils.getDictValue("hColor", "ding_message_corpconversation", "FFBBBBBB");
		String content = DictUtils.getDictValue("content", "ding_message_corpconversation", null);
		String author = DictUtils.getDictValue("author", "ding_message_corpconversation", "上海企树网络科技有限公司");
		if(StringUtils.isEmpty(content))
		{
			content = "您在 ${provider_name} 提交的工位预约单已经成功，请在钉钉内添加我们的客服人员，我们将尽快告知您预约结果。";
		}
		content = content.replace("${provider_name}", order.getOfficeResourcesName());
		CorpMessageCorpconversationAsyncsendRequest req = new CorpMessageCorpconversationAsyncsendRequest();
		req.setMsgtype("oa");
		req.setAgentId(agentId);
		req.setUseridList(userId);
		req.setToAllUser(false);
		req.setMsgcontentString("{\"message_url\": \"" + messageUrl + "\",\"head\": {\"bgcolor\": \"" + hColor + "\",\"text\": \"" + title + "\"},\"body\": {\"title\": \"" + title + "\",\"form\": [{\"key\": \"客服人员:\",\"value\": \"" + tel + "\"}],\"content\": \"" + content + "\"" + img + ",\"author\": \"" + author + " \"}}");
		System.out.println(req.getMsgcontent());
		CorpMessageCorpconversationAsyncsendResponse rsp;
		try {
			rsp = client.execute(req, access_token);
			System.out.println(rsp.getBody());
		} catch (ApiException e) {
			e.printStackTrace();
		}
	}
}
